package com.github.authcloud.server.configure.utils;

import com.github.authcloud.common.Logical;
import com.github.authcloud.common.NoRequiresLoginMapping;
import com.github.authcloud.common.RequiresRolePermissionMapping;

import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author : zhaoxuan
 * @version : 1.0
 * @date : 2021/8/22 16:04
 * @description : MappingCheckerUtil
 */
public class AuthRolePermissionMatchUtil {

    public static boolean isInNoLoginMappings(String url, String method, List<NoRequiresLoginMapping> noRequiresLoginMappings){
        if (noRequiresLoginMappings == null || noRequiresLoginMappings.isEmpty()) {
            return false;
        }
        return noRequiresLoginMappings.stream()
                .anyMatch(mapping -> mapping.getUrls().stream().anyMatch(url_ -> Pattern.matches(url_, url)) && mapping.getMethods().contains(method));
    }

    public static RequiresRolePermissionMapping getRequiresRolesPermissionsMapping(String url, String method, List<RequiresRolePermissionMapping> requiresRolePermissionMappings){
        if (requiresRolePermissionMappings == null || requiresRolePermissionMappings.isEmpty()) {
            return null;
        }
        return requiresRolePermissionMappings.stream()
                .filter(mapping -> mapping.getUrls().stream().anyMatch(url_ -> Pattern.matches(url_, url)) && mapping.getMethods().contains(method))
                .findFirst().orElse(null);
    }

    public static boolean checkRoles(List<String> userRoles, Set<String> requiresRoles, Logical logical){
        return checkRolesOrPermissions(userRoles, requiresRoles, logical);
    }

    public static boolean checkPermissions(List<String> userPermissions, Set<String> requiresPermissions, Logical logical){
        return checkRolesOrPermissions(userPermissions, requiresPermissions, logical);
    }

    private static boolean checkRolesOrPermissions(List<String> userRolesOrPermissions, Set<String> requiresRolesOrPermissions, Logical logical) {
        if (requiresRolesOrPermissions == null || requiresRolesOrPermissions.isEmpty()) {
            return true;
        }
        if (Logical.AND == logical) {
            return userRolesOrPermissions.containsAll(requiresRolesOrPermissions);
        } else {
            for (String requirePermission : requiresRolesOrPermissions) {
                if (userRolesOrPermissions.contains(requirePermission)) {
                    return true;
                }
            }
        }
        return false;
    }

}
